using System;
using System.Reflection;
using Microsoft.XLANGs.BaseTypes;

namespace TKH.BizTalk.Diagnostics
{
    /// <summary>
    /// Logger used to log events
    /// </summary>
    /// <remarks></remarks>
    public class Logger : TKH.BizTalk.Diagnostics.LogSource
    {
        private const string SOURCE = "BizTalk Orchestration";
        
        /// <summary>
        /// Creates start orchestration trace event in trace file 
        /// </summary>
        public static void TraceStartOrchestration()
        {
            System.Diagnostics.Trace.CorrelationManager.ActivityId = Microsoft.XLANGs.Core.Service.RootService.InstanceId;
            string serviceName = Microsoft.XLANGs.Core.Service.RootService.FullName;

            string orchestrationAssembly = Assembly.GetCallingAssembly().GetName().Name;

            BizTalkEvent biztalkEvent = new BizTalkEvent(System.Diagnostics.TraceEventType.Information,
                                                         orchestrationAssembly,
                                                         (int)EventId.BizTalkOrchestration,
                                                         "Orchestration Start",
                                                         Microsoft.XLANGs.Core.Service.RootService.ServiceId,
                                                         serviceName,
                                                         string.Empty,
                                                         new Activity(Microsoft.XLANGs.Core.Service.RootService.FullName, "Start"));

            TraceData(SOURCE, biztalkEvent);
        }

        /// <summary>
        /// Creates end orchestration trace event in trace file
        /// </summary>
        /// <param name="source">BizTalk application name</param>
        public static void TraceEndOrchestration()
        {
            System.Diagnostics.Trace.CorrelationManager.ActivityId = Microsoft.XLANGs.Core.Service.RootService.InstanceId;
            string serviceName = Microsoft.XLANGs.Core.Service.RootService.FullName;

            string orchestrationAssembly = Assembly.GetCallingAssembly().GetName().Name;

            BizTalkEvent biztalkEvent = new BizTalkEvent(System.Diagnostics.TraceEventType.Information,
                                                         orchestrationAssembly,
                                                         (int)EventId.BizTalkOrchestration,
                                                         "Orchestration End",
                                                         Microsoft.XLANGs.Core.Service.RootService.ServiceId,
                                                         serviceName,
                                                         string.Empty,
                                                         new Activity(Microsoft.XLANGs.Core.Service.RootService.FullName, "End"));

            TraceData(SOURCE, biztalkEvent);
        }

        /// <summary>
        /// Records message trace event in the trace file
        /// </summary>
        /// <param name="source">BizTalk application name</param>
        /// <param name="message">The XLANG message</param>
        public static void TraceMessage(XLANGMessage message)
        {
            try
            {
                System.Diagnostics.Trace.CorrelationManager.ActivityId = Microsoft.XLANGs.Core.Service.RootService.InstanceId;
                string serviceName = Microsoft.XLANGs.Core.Service.RootService.FullName;
                string orchestrationAssembly = Assembly.GetCallingAssembly().GetName().Name;

                Message traceMessage = new Message(message);
                BizTalkEvent biztalkEvent = new BizTalkEvent(System.Diagnostics.TraceEventType.Information,
                                                             orchestrationAssembly,
                                                             (int)EventId.BizTalkMessage,
                                                             message.Name,
                                                             Microsoft.XLANGs.Core.Service.RootService.ServiceId,
                                                             serviceName,
                                                             string.Empty,
                                                             traceMessage);

                TraceData(SOURCE, biztalkEvent);
            }
            finally
            {
                message.Dispose();
            }
        }

        /// <summary>
        /// Records a string trace event in trace file  
        /// </summary>
        /// <param name="source">BizTalk application name</param>
        /// <param name="message">User defined string</param>
        public static void TraceEvent(string message, params object[] args)
        {
            System.Diagnostics.Trace.CorrelationManager.ActivityId = Microsoft.XLANGs.Core.Service.RootService.InstanceId;
            string serviceName = Microsoft.XLANGs.Core.Service.RootService.FullName;

            string orchestrationAssembly = Assembly.GetCallingAssembly().GetName().Name;

            BizTalkEvent biztalkEvent = new BizTalkEvent(System.Diagnostics.TraceEventType.Information,
                                                         orchestrationAssembly,
                                                         (int)EventId.BizTalkEvent,
                                                         string.Format(message, args),
                                                         Microsoft.XLANGs.Core.Service.RootService.ServiceId,
                                                         serviceName,
                                                         string.Empty,
                                                         string.Format(message, args));

            TraceData(SOURCE, biztalkEvent);
        }

        /// <summary>
        /// Generates an warning logging event, written to event log
        /// </summary>
        /// <param name="source">BizTalk Application name</param>
        /// <param name="message">Exception</param>
        public static void LogErrorEvent(string message, params object[] args)
        {
            System.Diagnostics.Trace.CorrelationManager.ActivityId = Microsoft.XLANGs.Core.Service.RootService.InstanceId;
            string serviceName = Microsoft.XLANGs.Core.Service.RootService.FullName;

            string orchestrationAssembly = Assembly.GetCallingAssembly().GetName().Name;

            BizTalkEvent biztalkEvent = new BizTalkEvent(System.Diagnostics.TraceEventType.Error,
                                                         orchestrationAssembly,
                                                         (int)EventId.BizTalkException,
                                                         "Error",
                                                         Microsoft.XLANGs.Core.Service.RootService.ServiceId,
                                                         serviceName,
                                                         string.Format(message, args));

            TraceData(SOURCE, biztalkEvent);
        }

        /// <summary>
        /// Generates an warning logging event, written to event log
        /// </summary>
        /// <param name="source">BizTalk Application name</param>
        /// <param name="message">Exception</param>
        public static void LogWarning(string message, params object[] args)
        {
            System.Diagnostics.Trace.CorrelationManager.ActivityId = Microsoft.XLANGs.Core.Service.RootService.InstanceId;
            string serviceName = Microsoft.XLANGs.Core.Service.RootService.FullName;

            string orchestrationAssembly = Assembly.GetCallingAssembly().GetName().Name;

            BizTalkEvent biztalkEvent = new BizTalkEvent(System.Diagnostics.TraceEventType.Warning,
                                                         orchestrationAssembly,
                                                         (int)EventId.BizTalkWarning,
                                                         "Warning",
                                                         Microsoft.XLANGs.Core.Service.RootService.ServiceId,
                                                         serviceName,
                                                         string.Format(message, args));

            TraceData(SOURCE, biztalkEvent);
        }

        /// <summary>
        /// Generates an exception logging event, written to event log and fires WMI event
        /// </summary>
        /// <param name="source">BizTalk Application name</param>
        /// <param name="exception">Exception</param>
        public static void LogException(Exception exception)
        {
            System.Diagnostics.Trace.CorrelationManager.ActivityId = Microsoft.XLANGs.Core.Service.RootService.InstanceId;
            string serviceName = Microsoft.XLANGs.Core.Service.RootService.FullName;

            string orchestrationAssembly = Assembly.GetCallingAssembly().GetName().Name;

            BizTalkEvent biztalkEvent = new BizTalkEvent(System.Diagnostics.TraceEventType.Error,
                                                         orchestrationAssembly,
                                                         (int)EventId.BizTalkException,
                                                         "Exception",
                                                         Microsoft.XLANGs.Core.Service.RootService.ServiceId,
                                                         serviceName,
                                                         exception);

            TraceData(SOURCE, biztalkEvent);
        }

        /// <summary>
        /// Generates an message logging event, written to event log and fires WMI event
        /// </summary>
        /// <param name="source">BizTalk Application name</param>
        /// <param name="messageInError">XLANG message</param>
        public static void LogMessage(XLANGMessage messageInError)
        {
            try
            {
                System.Diagnostics.Trace.CorrelationManager.ActivityId = Microsoft.XLANGs.Core.Service.RootService.InstanceId;
                string serviceName = Microsoft.XLANGs.Core.Service.RootService.FullName;

                string orchestrationAssembly = Assembly.GetCallingAssembly().GetName().Name;

                Message message = new Message(messageInError);
                BizTalkEvent biztalkEvent = new BizTalkEvent(System.Diagnostics.TraceEventType.Error,
                                                             serviceName,
                                                             (int)EventId.BizTalkException,
                                                             "Message Error",
                                                             Microsoft.XLANGs.Core.Service.RootService.ServiceId,
                                                             serviceName,
                                                             message);

                TraceData(SOURCE, biztalkEvent);
            }
            finally
            {
                messageInError.Dispose();
            }
        }

        /// <summary>
        /// Generates an soap fault logging event, written to event log and fires WMI event
        /// </summary>
        /// <param name="source">BizTalk Application name</param>
        /// <param name="faultMessage">Soap Fault as an XLANG Message</param>
        public static void LogSoapFault(XLANGMessage faultMessage)
        {
            try
            {
                System.Diagnostics.Trace.CorrelationManager.ActivityId = Microsoft.XLANGs.Core.Service.RootService.InstanceId;
                string serviceName = Microsoft.XLANGs.Core.Service.RootService.FullName;

                string orchestrationAssembly = Assembly.GetCallingAssembly().GetName().Name;
                
                BizTalkEvent biztalkEvent = new BizTalkEvent(System.Diagnostics.TraceEventType.Error,
                                                             serviceName,
                                                             (int)EventId.BizTalkSoapFault,
                                                             "Soap Fault",
                                                             Microsoft.XLANGs.Core.Service.RootService.ServiceId,
                                                             serviceName,
                                                             new Message(faultMessage));

                TraceData(SOURCE, biztalkEvent);
            }
            finally
            {
                faultMessage.Dispose();
            }
        }
    }
}
